package com.brainwave.data;

import com.brainwave.models.BrainWaveData;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
import java.util.LinkedList;

/**
 * 数据滤波器类
 * 提供各种数据滤波和平滑算法，用于处理脑波数据中的噪声
 */
public class DataFilter {
    
    private static final String TAG = "DataFilter";
    
    // 滤波器类型枚举
    public enum FilterType {
        NONE,           // 无滤波
        MOVING_AVERAGE, // 移动平均
        MEDIAN,         // 中值滤波
        LOW_PASS,       // 低通滤波
        HIGH_PASS,      // 高通滤波
        BAND_PASS,      // 带通滤波
        KALMAN          // 卡尔曼滤波
    }
    
    // 滤波器配置
    public static class FilterConfig {
        public FilterType type = FilterType.MOVING_AVERAGE;
        public int windowSize = 5;          // 窗口大小
        public double cutoffFrequency = 0.1; // 截止频率
        public double samplingRate = 1.0;    // 采样率
        public double alpha = 0.1;           // 平滑因子
        
        public FilterConfig() {}
        
        public FilterConfig(FilterType type, int windowSize) {
            this.type = type;
            this.windowSize = windowSize;
        }
        
        public FilterConfig(FilterType type, double cutoffFrequency, double samplingRate) {
            this.type = type;
            this.cutoffFrequency = cutoffFrequency;
            this.samplingRate = samplingRate;
        }
    }
    
    // 移动平均滤波器
    public static class MovingAverageFilter {
        private final Queue<Double> window;
        private final int windowSize;
        private double sum = 0.0;
        
        public MovingAverageFilter(int windowSize) {
            this.windowSize = windowSize;
            this.window = new LinkedList<>();
        }
        
        public double filter(double value) {
            if (window.size() >= windowSize) {
                sum -= window.poll();
            }
            
            window.offer(value);
            sum += value;
            
            return sum / window.size();
        }
        
        public void reset() {
            window.clear();
            sum = 0.0;
        }
    }
    
    // 中值滤波器
    public static class MedianFilter {
        private final Queue<Double> window;
        private final int windowSize;
        
        public MedianFilter(int windowSize) {
            this.windowSize = windowSize;
            this.window = new LinkedList<>();
        }
        
        public double filter(double value) {
            if (window.size() >= windowSize) {
                window.poll();
            }
            
            window.offer(value);
            
            List<Double> sortedValues = new ArrayList<>(window);
            Collections.sort(sortedValues);
            
            int size = sortedValues.size();
            if (size % 2 == 0) {
                return (sortedValues.get(size / 2 - 1) + sortedValues.get(size / 2)) / 2.0;
            } else {
                return sortedValues.get(size / 2);
            }
        }
        
        public void reset() {
            window.clear();
        }
    }
    
    // 低通滤波器 (一阶RC滤波器)
    public static class LowPassFilter {
        private double alpha;
        private double previousOutput = 0.0;
        private boolean isInitialized = false;
        
        public LowPassFilter(double cutoffFrequency, double samplingRate) {
            double rc = 1.0 / (2 * Math.PI * cutoffFrequency);
            double dt = 1.0 / samplingRate;
            this.alpha = dt / (rc + dt);
        }
        
        public LowPassFilter(double alpha) {
            this.alpha = alpha;
        }
        
        public double filter(double value) {
            if (!isInitialized) {
                previousOutput = value;
                isInitialized = true;
                return value;
            }
            
            previousOutput = alpha * value + (1 - alpha) * previousOutput;
            return previousOutput;
        }
        
        public void reset() {
            previousOutput = 0.0;
            isInitialized = false;
        }
    }
    
    // 高通滤波器
    public static class HighPassFilter {
        private double alpha;
        private double previousInput = 0.0;
        private double previousOutput = 0.0;
        private boolean isInitialized = false;
        
        public HighPassFilter(double cutoffFrequency, double samplingRate) {
            double rc = 1.0 / (2 * Math.PI * cutoffFrequency);
            double dt = 1.0 / samplingRate;
            this.alpha = rc / (rc + dt);
        }
        
        public double filter(double value) {
            if (!isInitialized) {
                previousInput = value;
                previousOutput = value;
                isInitialized = true;
                return 0.0;
            }
            
            previousOutput = alpha * (previousOutput + value - previousInput);
            previousInput = value;
            return previousOutput;
        }
        
        public void reset() {
            previousInput = 0.0;
            previousOutput = 0.0;
            isInitialized = false;
        }
    }
    
    // 简单卡尔曼滤波器
    public static class KalmanFilter {
        private double processNoise;    // 过程噪声
        private double measurementNoise; // 测量噪声
        private double estimation;      // 估计值
        private double errorCovariance; // 误差协方差
        private boolean isInitialized = false;
        
        public KalmanFilter(double processNoise, double measurementNoise) {
            this.processNoise = processNoise;
            this.measurementNoise = measurementNoise;
            this.errorCovariance = 1.0;
        }
        
        public double filter(double measurement) {
            if (!isInitialized) {
                estimation = measurement;
                isInitialized = true;
                return measurement;
            }
            
            // 预测步骤
            double predictedEstimation = estimation;
            double predictedErrorCovariance = errorCovariance + processNoise;
            
            // 更新步骤
            double kalmanGain = predictedErrorCovariance / (predictedErrorCovariance + measurementNoise);
            estimation = predictedEstimation + kalmanGain * (measurement - predictedEstimation);
            errorCovariance = (1 - kalmanGain) * predictedErrorCovariance;
            
            return estimation;
        }
        
        public void reset() {
            estimation = 0.0;
            errorCovariance = 1.0;
            isInitialized = false;
        }
    }
    
    // 组合滤波器
    public static class CompositeFilter {
        private final List<Object> filters;
        
        public CompositeFilter() {
            this.filters = new ArrayList<>();
        }
        
        public void addFilter(Object filter) {
            filters.add(filter);
        }
        
        public double filter(double value) {
            double result = value;
            
            for (Object filter : filters) {
                if (filter instanceof MovingAverageFilter) {
                    result = ((MovingAverageFilter) filter).filter(result);
                } else if (filter instanceof MedianFilter) {
                    result = ((MedianFilter) filter).filter(result);
                } else if (filter instanceof LowPassFilter) {
                    result = ((LowPassFilter) filter).filter(result);
                } else if (filter instanceof HighPassFilter) {
                    result = ((HighPassFilter) filter).filter(result);
                } else if (filter instanceof KalmanFilter) {
                    result = ((KalmanFilter) filter).filter(result);
                }
            }
            
            return result;
        }
        
        public void reset() {
            for (Object filter : filters) {
                if (filter instanceof MovingAverageFilter) {
                    ((MovingAverageFilter) filter).reset();
                } else if (filter instanceof MedianFilter) {
                    ((MedianFilter) filter).reset();
                } else if (filter instanceof LowPassFilter) {
                    ((LowPassFilter) filter).reset();
                } else if (filter instanceof HighPassFilter) {
                    ((HighPassFilter) filter).reset();
                } else if (filter instanceof KalmanFilter) {
                    ((KalmanFilter) filter).reset();
                }
            }
        }
    }
    
    // 脑波数据滤波器
    public static class BrainWaveDataFilter {
        private final MovingAverageFilter attentionFilter;
        private final MovingAverageFilter meditationFilter;
        private final MedianFilter signalQualityFilter;
        private final LowPassFilter rawDataFilter;
        
        public BrainWaveDataFilter(FilterConfig config) {
            this.attentionFilter = new MovingAverageFilter(config.windowSize);
            this.meditationFilter = new MovingAverageFilter(config.windowSize);
            this.signalQualityFilter = new MedianFilter(config.windowSize);
            this.rawDataFilter = new LowPassFilter(config.alpha);
        }
        
        public BrainWaveData filter(BrainWaveData data) {
            BrainWaveData filteredData = new BrainWaveData();
            
            // 复制基本信息
            filteredData.setTimestamp(data.getTimestamp());
            filteredData.setSessionId(data.getSessionId());
            filteredData.setDeviceName(data.getDeviceName());
            filteredData.setDeviceAddress(data.getDeviceAddress());
            filteredData.setDataSource(data.getDataSource());
            
            // 滤波处理
            filteredData.setAttention((int) attentionFilter.filter(data.getAttention()));
            filteredData.setMeditation((int) meditationFilter.filter(data.getMeditation()));
            filteredData.setPoorSignal((int) signalQualityFilter.filter(data.getPoorSignal()));
            filteredData.setRawValue((int) rawDataFilter.filter(data.getRawValue()));
            
            // EEG功率数据使用低通滤波
            filteredData.setDelta(data.getDelta());
            filteredData.setTheta(data.getTheta());
            filteredData.setLowAlpha(data.getLowAlpha());
            filteredData.setHighAlpha(data.getHighAlpha());
            filteredData.setLowBeta(data.getLowBeta());
            filteredData.setHighBeta(data.getHighBeta());
            filteredData.setLowGamma(data.getLowGamma());
            filteredData.setHighGamma(data.getHighGamma());
            
            // 其他数据
            filteredData.setBlinkStrength(data.getBlinkStrength());
            filteredData.setValid(data.isValid());
            
            return filteredData;
        }
        
        public void reset() {
            attentionFilter.reset();
            meditationFilter.reset();
            signalQualityFilter.reset();
            rawDataFilter.reset();
        }
    }
    
    /**
     * 创建滤波器
     */
    public static Object createFilter(FilterConfig config) {
        switch (config.type) {
            case MOVING_AVERAGE:
                return new MovingAverageFilter(config.windowSize);
            case MEDIAN:
                return new MedianFilter(config.windowSize);
            case LOW_PASS:
                return new LowPassFilter(config.cutoffFrequency, config.samplingRate);
            case HIGH_PASS:
                return new HighPassFilter(config.cutoffFrequency, config.samplingRate);
            case KALMAN:
                return new KalmanFilter(0.01, 0.1); // 默认噪声参数
            default:
                return null;
        }
    }
    
    /**
     * 批量滤波处理
     */
    public static List<BrainWaveData> filterDataList(List<BrainWaveData> dataList, FilterConfig config) {
        if (dataList == null || dataList.isEmpty()) {
            return new ArrayList<>();
        }
        
        BrainWaveDataFilter filter = new BrainWaveDataFilter(config);
        List<BrainWaveData> filteredList = new ArrayList<>();
        
        for (BrainWaveData data : dataList) {
            filteredList.add(filter.filter(data));
        }
        
        return filteredList;
    }
    
    /**
     * 异常值检测和处理
     */
    public static List<BrainWaveData> removeOutliers(List<BrainWaveData> dataList, double threshold) {
        if (dataList == null || dataList.size() < 3) {
            return dataList;
        }
        
        List<BrainWaveData> cleanedList = new ArrayList<>();
        
        // 计算注意力和冥想的平均值和标准差
        double attentionMean = dataList.stream().mapToInt(BrainWaveData::getAttention).average().orElse(0);
        double meditationMean = dataList.stream().mapToInt(BrainWaveData::getMeditation).average().orElse(0);
        
        double attentionStd = Math.sqrt(dataList.stream()
            .mapToDouble(data -> Math.pow(data.getAttention() - attentionMean, 2))
            .average().orElse(0));
        
        double meditationStd = Math.sqrt(dataList.stream()
            .mapToDouble(data -> Math.pow(data.getMeditation() - meditationMean, 2))
            .average().orElse(0));
        
        // 过滤异常值
        for (BrainWaveData data : dataList) {
            boolean isAttentionNormal = Math.abs(data.getAttention() - attentionMean) <= threshold * attentionStd;
            boolean isMeditationNormal = Math.abs(data.getMeditation() - meditationMean) <= threshold * meditationStd;
            boolean isSignalGood = data.getPoorSignal() < 100; // 信号质量阈值
            
            if (isAttentionNormal && isMeditationNormal && isSignalGood) {
                cleanedList.add(data);
            }
        }
        
        return cleanedList;
    }
    
    /**
     * 数据平滑处理
     */
    public static List<BrainWaveData> smoothData(List<BrainWaveData> dataList, int windowSize) {
        if (dataList == null || dataList.size() < windowSize) {
            return dataList;
        }
        
        List<BrainWaveData> smoothedList = new ArrayList<>();
        
        for (int i = 0; i < dataList.size(); i++) {
            int start = Math.max(0, i - windowSize / 2);
            int end = Math.min(dataList.size() - 1, i + windowSize / 2);
            
            // 计算窗口内的平均值
            double avgAttention = 0;
            double avgMeditation = 0;
            int count = 0;
            
            for (int j = start; j <= end; j++) {
                BrainWaveData data = dataList.get(j);
                avgAttention += data.getAttention();
                avgMeditation += data.getMeditation();
                count++;
            }
            
            avgAttention /= count;
            avgMeditation /= count;
            
            // 创建平滑后的数据
            BrainWaveData smoothedData = new BrainWaveData();
            BrainWaveData originalData = dataList.get(i);
            
            // 复制原始数据
            smoothedData.setTimestamp(originalData.getTimestamp());
            smoothedData.setSessionId(originalData.getSessionId());
            smoothedData.setDeviceName(originalData.getDeviceName());
            smoothedData.setDeviceAddress(originalData.getDeviceAddress());
            smoothedData.setPoorSignal(originalData.getPoorSignal());
            smoothedData.setRawValue(originalData.getRawValue());
            smoothedData.setBlinkStrength(originalData.getBlinkStrength());
            
            // 设置平滑后的值
            smoothedData.setAttention((int) Math.round(avgAttention));
            smoothedData.setMeditation((int) Math.round(avgMeditation));
            
            // EEG数据保持不变
            smoothedData.setDelta(originalData.getDelta());
            smoothedData.setTheta(originalData.getTheta());
            smoothedData.setLowAlpha(originalData.getLowAlpha());
            smoothedData.setHighAlpha(originalData.getHighAlpha());
            smoothedData.setLowBeta(originalData.getLowBeta());
            smoothedData.setHighBeta(originalData.getHighBeta());
            smoothedData.setLowGamma(originalData.getLowGamma());
            smoothedData.setHighGamma(originalData.getHighGamma());
            
            smoothedData.setValid(originalData.isValid());
            smoothedData.setDataSource(originalData.getDataSource() + "_smoothed");
            
            smoothedList.add(smoothedData);
        }
        
        return smoothedList;
    }
}